package com.lagou.session;

import com.lagou.handler.MapperProxy;
import com.lagou.handler.DefaultResultSetHandler;
import com.lagou.pojo.Configuration;
import com.lagou.pojo.MappedStatement;

import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

public class DefaultSqlSession implements SqlSession {

    private final Configuration configuration;
    private final Executor executor;
    private final boolean autoCommit;

    public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
        this.configuration = configuration;
        this.executor = executor;
        this.autoCommit = autoCommit;
    }
    public DefaultSqlSession(Configuration configuration, Executor executor) {
        this(configuration, executor, false);
    }

    @Override
    public <E> List<E> selectList(String statementId, Object parameter) throws Exception {

        MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
        //将要去完成对simpleExecutor里的query方法的调用
        List<Object> list = executor.query(configuration,new DefaultResultSetHandler(mappedStatement), mappedStatement, parameter);

        return (List<E>) list;
    }

    @Override
    public <T> T selectOne(String statementId, Object parameter) throws Exception {
        List<Object> objects = selectList(statementId, parameter);
        if(objects.size()==1){
            return (T) objects.get(0);
        }else {
            throw new RuntimeException("查询结果为空或者返回结果过多");
        }


    }

    @Override
    public int insert(String statementId, Object parameter) throws Exception {
        return this.update(statementId, parameter);
    }

    @Override
    public int update(String statementId, Object parameter) throws Exception {
        MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
        return executor.update(configuration,mappedStatement,parameter);
    }

    @Override
    public int delete(String statementId, Object parameter) throws Exception {
        return this.update(statementId, parameter);
    }

    @Override
    public void commit() throws Exception {
        this.executor.commit(this.autoCommit);
    }

    @Override
    public void rollback() throws Exception {
        this.executor.rollback(this.autoCommit);
    }

    @Override
    public void close() {
        this.executor.close(autoCommit);
    }

    @Override
    public <T> T getMapper(Class<?> mapperClass) {
        // 使用JDK动态代理来为Dao接口生成代理对象，并返回
        Object proxyInstance =
                Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{mapperClass},new MapperProxy<T>(this));

        return (T) proxyInstance;
    }

    @Override
    public Configuration getConfiguration() {
        return this.configuration;
    }

    @Override
    public Connection getConnection() {
        try {
            return this.executor.getTransaction().getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

}
